package com.net;

import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by whf on 16/5/14.
 */
public class ReqParam {


    private ReqParam(){}

    private String server;
    private String app_id;
    private String data;

    @Override
    public String toString() {
        return data;
    }

    public static class Builder{
        private String server;
        private String app_id;
        private StringBuilder data;

        public Builder(String server){
            this.server=server;
            data=new StringBuilder("");
        }

        public Builder putString(String str){
            if(data.length()>0){
                data.append('&');
            }
            data.append(str);
            return this;
        }

        public Builder putArray(ArrayList<String[]> lst){
            if(lst!=null){
                if(data.length()>0){
                    data.append('&');
                }
                for (int i = 0,lstSize=lst.size(); i < lstSize; i++) {
                    if(i>0 && i<lstSize){
                        data.append('~');
                    }
                    String[]arr=lst.get(i);
                    for (int j = 0,strSize=arr.length; j <strSize ; j++) {
                        if(j>0 && j<strSize){
                            data.append('|');
                        }
                        data.append(arr[j]);
                    }
                }
            }
            return this;
        }


		/**
		 * <pre>添加对象数据，IKeySort 实现类</pre>
		 * @param keySortImpl
		 * @return Builder
		 */
		@SuppressWarnings("unchecked")
		public Builder putObj(IKeySort keySortImpl){
			if(keySortImpl!=null){
				String[]keys=keySortImpl.getKeySort();
				Class<?>clazz=keySortImpl.getClass();
				try {
					for(int i=0;i<keys.length;i++){
						Field field= clazz.getDeclaredField(keys[i]);
						field.setAccessible(true);
						if(field.getType().isAssignableFrom(List.class)
								||field.getType().isAssignableFrom(ArrayList.class)){
							//包含集合数据
							addArrayObj((List<IKeySort>) field.get(keySortImpl),field.getGenericType());
						}else{
							Object val = field.get(keySortImpl);
							addObj(val,Character.SEPARATOR_DATA);
						}
					}
				} catch (NoSuchFieldException e) {
					System.out.println("error = [" + e.getMessage() + "] 没有相应的字段属性");
				} catch (IllegalAccessException e) {
					System.out.println("error = [" + e.getMessage() + "]");
				} catch (IllegalArgumentException e) {
					System.out.println("error = [" + e.getMessage() + "]");
				}
			}
			
			return this;
		}
		
		/**
		 * <pre>添加数组Objcet</pre>
		 * @param list IKeySort
		 * @param clzz
		 * @return Builder
		 */
		public Builder putArrayObj(List<?>list,Class<?>clzz){
			addArray(list, clzz);
			return this;
		}
		
		/*
		 * 添加对象数据
		 */
		private void addObj(Object obj,String separate){
			if (data.length() > 0) {
				data.append(separate);
			}
			data.append(obj==null?"":obj.toString());
		}
		
		/*
		 * <pre>添加List数据</pre>
		 * @param list 需要实现IKeySort
		 * @param type
		 * @return void
		 */
		
		private void addArrayObj(List<?> list,Type type){
			if (!(type instanceof ParameterizedType)) {//
				System.out.println("error = [type is not ParameterizedType]");
				return ;
			}
			Type[] params = ((ParameterizedType) type).getActualTypeArguments();
			Type t = params[0];
			addArray(list, t);
		}

		
		/**
		 * <pre>todo</pre>
		 * @param list
		 * @param t
		 * @return void
		*/
		@SuppressWarnings("unchecked")
		private void addArray(List<?> list, Type t) {
			if(list==null || list.size()<1){
				System.out.println("error = [list is null]");
				return ;
			}
			Class<? super IKeySort> clazz = (Class<? super IKeySort>) t;
			String[] keySort =((IKeySort) list.get(0)).getKeySort();
			if(keySort==null||keySort.length<1){
				System.out.println("error = [list is not keySort]");
				return;
			}
			try {
				if(data.length()>0){
					 data.append(Character.SEPARATOR_DATA);
				}
				//int arrLen,vaLen;
				for(int k=0,arrLen=list.size();k<arrLen;k++){
					IKeySort keySortIpm=(IKeySort) list.get(k);
					if (k > 0 && k < arrLen) {
						data.append(Character.SEPARATOR_COMMA);
					}
					for (int i = 0,vaLen=keySort.length; i < vaLen; i++) {
						if (i > 0 && i < vaLen) {
							data.append(Character.SEPARATOR_WELLS);
						}
						Field field = clazz.getDeclaredField(keySort[i]);
						field.setAccessible(true);
						Object val = field.get(keySortIpm);
						data.append(val==null?"":val.toString());
					}	
				}
				
			} catch (NoSuchFieldException e) {
				System.out.println("error = [" + e.getMessage() + "] 没有相应的字段属性");
			} catch (IllegalAccessException e) {
				System.out.println("error = [" + e.getMessage() + "]");
			} catch (IllegalArgumentException e) {
				System.out.println("error = [" + e.getMessage() + "]");
			}
		}
        
        
        public ReqParam create(){
            ReqParam param=new ReqParam();
            param.server=server;
            param.data=data.toString();
            return param;
        }

    }



}
